home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PCMania 30
/
PCMania CD30.iso
/
pcmania
/
graf30
/
dtiff2.c
< prev
next >
Wrap
Text File
|
1988-11-28
|
9KB
|
274 lines
/*****************************************************************************
DTIFF2.C - DTIFF2, Display Tag Image File Format.
Modified by Tom Cervenka for Late Night Software, (c) 1988
All Rights Reserved.
This code was modified from source mentioned in BYTE Vol 13, Num 11,
"IBM Special Edition", "VGA VIDEO MODES", p. 187, by Richard Wilton
and downloaded via BIX LISTINGS Conference.
*****************************************************************************/
/******************************************************************************
* *
* Name: gvmode.c *
* *
* Function: program VGA CRTC in graphics modes *
* *
* Syntax: GVMODE <horizontal pixels> <vertical pixels> [adjust] *
* *
******************************************************************************/
#include <stdio.h>
#include <dos.h>
#define outpw(portid,v) outport(portid,v)
#define DOTRATE0 25.175E6
#define DOTRATE1 28.322E6
#define CHARHEIGHT 16 /* (should be 8, 14, or 16) */
int far *ADDR_6845 = (int far *)0x00400063;
union REGS regs; /* used by int86() */
char *vgaxset( int HPixels, int VPixels, int HAdjust )
{
float DotRate;
float LineRate;
float FrameRate;
float HSyncDuration = 3.813E-6; /* duration of HSync signal */
int CharWidth = 8; /* size of displayed characters */
int CharHeight = CHARHEIGHT;
/* ROM BIOS data values */
unsigned int far *CRT_COLS = (int far *)0x0040004A;
unsigned int far *CRT_LEN = (int far *)0x0040004C;
int Cols; /* number of displayed character columns */
int HSyncTime; /* number of horiz sync clocks */
int HOverscan = 8; /* number of overscan clocks */
int HTotal; /* total clocks in one horiz scan */
/* int HAdjust = 0; */ /* horizontal adjustment */
/* int HPixels; */ /* number of horizontal pixels */
int VOverscan = 16; /* number of overscan scan lines */
int VSyncTime = 2; /* number of scan lines of vert sync signal */
int VRetrTime = 30; /* number of scan lines of vertical retrace */
/* int VPixels; */ /* number of vertical pixels (scan lines) */
int CRTCval[0x19]; /* values for CRTC regs */
int i;
/* check args */
if( HPixels % 16 )
{
return("Error: Horizontal pixel count must be a multiple of 16\n");
}
/* start with either 640x350 or 640x480 16-color graphics mode */
regs.x.ax = ( (VPixels <= 350) ? 0x0010 : 0x0012 );
int86( 0x10, ®s, ®s );
/* call BIOS to select displayed character matrix */
regs.x.ax = 0x1100;
switch( CharHeight )
{
case 8:
regs.x.ax += 0x23; /* use 8x8 character definitions */
break;
case 14:
regs.x.ax += 0x22; /* use 8x14 character definitions */
break;
case 16:
regs.x.ax += 0x24; /* use 8x14 character definitions */
break;
}
regs.x.bx = 0;
regs.x.dx = VPixels / CharHeight; /* number of character rows */
int86( 0x10, ®s, ®s );
/* select dot clock */
i = inp( 0x3CC ); /* read Miscellaneous Output reg */
i &= 0xF3; /* bits 2-3 = 00b (25.172 MHz) */
if( (unsigned)((HPixels/CharWidth)*VPixels) > (unsigned)((640/8)*480) )
i |= 4; /* bits 2-3 = 01b (28.322 MHz) */
VRwait();
SetSeqReg( 0, 1 ); /* synchronous Sequencer reset */
outp( 0x3C2, i ); /* update Misc Output reg */
SetSeqReg( 0, 3 ); /* clear Sequencer reset */
/* compute CRTC horizontal and vertical timing parameters */
DotRate = ( ((inp(0x3CC) & 0x0C) == 0) ? DOTRATE0 : DOTRATE1);
HSyncTime = /* duration of Horiz Sync signal (rounded) */
( (DotRate * HSyncDuration) / (float)CharWidth ) + 0.5;
Cols = HPixels / CharWidth;
HTotal = Cols + HSyncTime + HOverscan;
for( i=0; i<=0x18; i++ ) /* get current CRTC register values */
CRTCval[i] = GetCRTCReg( i );
CRTCval[0] = HTotal - 5; /* Reg 0: Horiz Total */
CRTCval[1] = Cols - 1; /* Reg 1: Horiz Disp Enable End */
CRTCval[2] = Cols; /* Reg 2: Start Horiz Blank */
CRTCval[3] = ((HTotal-2) & 0x1F) | 0x80; /* Reg 3: End Horiz Blank */
CRTCval[4] = Cols + HAdjust + 4; /* Reg 4: Start Hsync */
CRTCval[5] = /* Reg 5: End Hsync */
((CRTCval[4] + HSyncTime) & 0x1F) | /* bits 0-4 */
(((HTotal-2) & 0x20) << 2); /* bit 7 */
CRTCval[0x13] = Cols / 2; /* Reg 0x13: Offset */
CRTCval[6] = /* Reg 6: Vertical Total */
VPixels + VOverscan + VSyncTime + VRetrTime - 2;
CRTCval[0x10] = /* Reg 0x10: Vert Retrace Start */
VPixels + (VOverscan+VRetrTime)/2;
CRTCval[0x11] = /* Reg 0x11: Vert Retrace End */
(CRTCval[0x11] & 0xF0) | /* bits 4-7 */
((CRTCval[0x10] + VSyncTime) & 0x0F); /* bits 0-3 */
CRTCval[0x12] = VPixels - 1; /* Reg 0x12: Vert Display Enable End */
CRTCval[0x15] = /* Reg 0x15: Start Vert Blank */
VPixels + VOverscan/2;
CRTCval[0x16] = /* Reg 0x16: End Vert Blank */
CRTCval[6] - VOverscan/2 + 2;
CRTCval[7] = /* Reg 7: Overflow */
((CRTCval[0x10] & 0x200) >> 2) | /* bit 7 */
((CRTCval[0x12] & 0x200) >> 3) | /* bit 6 */
((CRTCval[6] & 0x200) >> 4) | /* bit 5 */
(CRTCval[7] & 0x10) | /* bit 4 */
((CRTCval[0x15] & 0x100) >> 5) | /* bit 3 */
((CRTCval[0x10] & 0x100) >> 6) | /* bit 2 */
((CRTCval[0x12] & 0x100) >> 7) | /* bit 1 */
((CRTCval[6] & 0x100) >> 8); /* bit 0 */
CRTCval[9] = /* Reg 9: Max Scan Line */
(CRTCval[9] & 0xDF) | ((CRTCval[0x15] & 0x200) >> 4); /* bit 5 */
/* program the CRTC with new timing parameters */
CRTCval[0x11] &= 0x7F; /* disable CRTC write-protect */
SetCRTCReg( 0x11, CRTCval[0x11] );
for( i=0; i<=0x18; i++ )
SetCRTCReg( i, CRTCval[i] ); /* update CRTC regs */
CRTCval[0x11] |= 0x80; /* enable CRTC write-protect */
SetCRTCReg( 0x11, CRTCval[0x11] );
SetATCReg( 0x11, 1 ); /* set a blue border (for screen alignment) */
/* update BIOS data area */
*CRT_COLS = Cols;
*CRT_LEN = ((VPixels * Cols * 2) + 0xFFF) & 0xF000;
/* display register values and timings */
/*
printf( "\nDisplayed resolution is %d by %d pixels",
HPixels, VPixels );
printf( "\nDisplayed character matrix is %d by %d pixels",
CharWidth, CharHeight );
printf( "\n\nCRTC registers:\n" ); /* show CRTC register values */
for( i=0; i<=0x18; i++ )
printf( " %2X", i );
printf( "\n" );
for( i=0; i<=0x18; i++ )
printf( " %2X", GetCRTCReg( i ) );
LineRate = /* scan lines per second */
DotRate / (float)((CRTCval[0]+5)*CharWidth);
i = ((GetCRTCReg(7) & 0x20) << 4) /* vertical total (scan lines) */
+ ((GetCRTCReg(7) & 0x1) << 8)
+ GetCRTCReg(6) + 2;
FrameRate = LineRate / (float)i; /* frames per second */
printf( "\n\nDot rate = %6.3f MHz, %d dots/char",
DotRate/1E6, CharWidth );
printf( "\nLine rate = %5.2f KHz", LineRate/1E3 );
printf( "\nFrame rate = %4.1f Hz\n", FrameRate );
*/
return(NULL);
}
SetCRTCReg( r, v ) /* update a CRTC register */
int r; /* register number */
int v; /* 8-bit value */
{
outpw( *ADDR_6845, (v<<8) | r );
}
GetCRTCReg( r ) /* read a CRTC register */
int r; /* register number */
{
outp( *ADDR_6845, r );
return inp( *ADDR_6845+1 );
}
SetSeqReg( r, v ) /* update a Sequencer register */
int r;
int v;
{
outpw( 0x3C4, (v<<8) | r );
}
SetATCReg( r, v ) /* set an Attribute Controller register */
int r;
int v;
{
regs.x.ax = 0x1000;
regs.h.bh = v;
regs.h.bl = r;
int86( 0x10, ®s, ®s ); /* use video BIOS to set register */
}
VRwait() /* wait for vertical retrace */
{
register int CRTStatusPort = *ADDR_6845 + 6;
while( (inp( CRTStatusPort ) & 8) != 0 );
while( (inp( CRTStatusPort ) & 8) == 0 );
}
/* The following code was written by Tom Cervenka */
extern int MaxX;
void vgaxputpixel(int x, int y, int color)
{
unsigned offset;
static unsigned char far *pixpos;
offset=(x/8)+(y*((MaxX+1)/8));
pixpos=MK_FP(0xa000,offset);
*pixpos=(*pixpos)|(1<<(7-(x%8)));
}
void hercputpixel(int x, int y, int color)
{
unsigned offset;
static unsigned char far *pixpos;
offset=(0x2000*(y%4))+(90*(y/4))+(x/8);
pixpos=MK_FP(0xB000,offset);
*pixpos=(*pixpos)&(~(1<<(7-(x%8))));
}
void cgaputpixel(int x, int y, int color)
{
unsigned offset;
static unsigned char far *pixpos;
offset=(0x2000*(y%2))+(80*(y/2))+(x/8);
pixpos=MK_FP(0xB800,offset);
*pixpos=(*pixpos)&(~(1<<(7-(x%8))));
}